"""卖家对话消息数据访问层"""

from datetime import datetime
from typing import List, Tuple

from sqlalchemy import and_, desc, func, select, update, delete, or_
from sqlalchemy.ext.asyncio import AsyncSession

from module_admin.entity.do.seller_message_do import SellerMessage
from module_admin.entity.vo.seller_message_vo import SellerMessageQueryModel


class SellerMessageDao:
    """卖家消息 DAO"""

    @classmethod
    async def get_message_list(
        cls,
        db: AsyncSession,
        query_params: SellerMessageQueryModel,
        page_num: int = 1,
        page_size: int = 10,
        current_user_id: int = None,
        is_admin: bool = True
    ) -> Tuple[List[SellerMessage], int]:
        """分页查询卖家消息（支持权限过滤）
        
        Args:
            db: 数据库会话
            query_params: 查询参数
            page_num: 页码
            page_size: 每页数量
            current_user_id: 当前用户ID
            is_admin: 是否是管理员（role_id=1的超级管理员）
        """

        conditions = [SellerMessage.del_flag == '0']

        # ⚠️ 权限过滤：非管理员只能看到分配给自己的agent的聊天记录
        if not is_admin and current_user_id:
            from module_admin.entity.do.client_do import AgentClient
            # 查询分配给当前用户的所有agent的client_id列表（1对1分配）
            agent_query = select(AgentClient.client_id).where(
                AgentClient.del_flag == '0',
                AgentClient.assigned_user_id == current_user_id
            )
            agent_result = await db.execute(agent_query)
            allowed_client_ids = [row[0] for row in agent_result.all()]
            
            if allowed_client_ids:
                # 只查询分配给当前用户的agent的聊天记录
                conditions.append(SellerMessage.client_id.in_(allowed_client_ids))
            else:
                # 如果当前用户没有分配任何agent，返回空结果
                conditions.append(SellerMessage.client_id.is_(None))  # 永远不会匹配的条件

        if query_params.conversation_id:
            conditions.append(SellerMessage.conversation_id == query_params.conversation_id)
        if query_params.seller_id:
            conditions.append(SellerMessage.seller_id == query_params.seller_id)
        if query_params.seller_name:
            conditions.append(SellerMessage.seller_name.like(f"%{query_params.seller_name}%"))
        if query_params.client_id:
            conditions.append(SellerMessage.client_id == query_params.client_id)
        if query_params.item_id:
            conditions.append(SellerMessage.item_id == query_params.item_id)
        if query_params.message_type:
            conditions.append(SellerMessage.message_type == query_params.message_type)
        if query_params.direction:
            conditions.append(SellerMessage.direction == query_params.direction)

        if query_params.start_time:
            start_time = cls._ensure_datetime(query_params.start_time)
            if start_time:
                conditions.append(SellerMessage.message_time >= start_time)
        if query_params.end_time:
            end_time = cls._ensure_datetime(query_params.end_time)
            if end_time:
                conditions.append(SellerMessage.message_time <= end_time)

        condition_expr = and_(*conditions)

        total_stmt = select(func.count()).select_from(SellerMessage).where(condition_expr)
        total_result = await db.execute(total_stmt)
        total = total_result.scalar_one() or 0

        stmt = (
            select(SellerMessage)
            .where(condition_expr)
            .order_by(desc(SellerMessage.message_time))
            .limit(page_size)
            .offset((page_num - 1) * page_size)
        )
        result = await db.execute(stmt)
        rows = result.scalars().all()
        
        # ✅ 去重：如果有相同的message_id，只保留最新的记录（按id排序，保留id最大的）
        seen_message_ids = set()
        unique_rows = []
        for row in rows:
            if row.message_id not in seen_message_ids:
                seen_message_ids.add(row.message_id)
                unique_rows.append(row)
        
        if len(unique_rows) < len(rows):
            from utils.log_util import logger
            logger.warning(f"[DAO] 检测到重复消息：查询返回 {len(rows)} 条，去重后 {len(unique_rows)} 条")

        return unique_rows, total

    @classmethod
    async def create_message(cls, db: AsyncSession, message: SellerMessage) -> SellerMessage:
        db.add(message)
        await db.flush()
        await db.refresh(message)
        return message

    @classmethod
    async def update_message(cls, db: AsyncSession, message_id: int, update_data: dict):
        stmt = (
            update(SellerMessage)
            .where(SellerMessage.id == message_id, SellerMessage.del_flag == '0')
            .values(**update_data)
        )
        await db.execute(stmt)

    @classmethod
    async def delete_message(cls, db: AsyncSession, message_id: int):
        stmt = (
            delete(SellerMessage)
            .where(SellerMessage.id == message_id)
        )
        await db.execute(stmt)

    @staticmethod
    def _ensure_datetime(value):
        if value is None:
            return None
        if isinstance(value, datetime):
            return value
        try:
            return datetime.fromisoformat(str(value))
        except ValueError:
            return None
